'''
Created on Sept 16, 2013

@author: Patrick Janssen
'''

import sys, os
from string import Template
from core.modules.vistrails_module import Module, ModuleError
import json
from constants import *

''' ---------------------------------------------------------------------------
TransFilter
--------------------------------------------------------------------------- '''
class TransFilter(Module):
    def compute(self):

        # Check inputs
        if not self.hasInputFromPort("json_input_file"):
            raise ModuleError(self, "Needs json_input")
        if not self.hasInputFromPort("filter_data"):
            raise ModuleError(self, "Needs filter_data")
        json_input_file = self.getInputFromPort("json_input_file")
        filter_data = self.getInputFromPort("filter_data")

        #Get the paths of the files
        json_input_file_path = os.path.abspath(json_input_file.name)

        #Get the json data
        with open(json_input_file_path) as input_file:    
            input_data = json.load(input_file)

        #Polys from input to output
        output_data = {"points":[],"polys":[]}
        for poly in input_data["polys"]:
        	attribs = poly["attributes"]
        	if filter_data[0] in attribs.keys() and attribs[filter_data[0]]["value"] == filter_data[1]:
        		output_data["polys"].append(poly)
        
        #Points from input to putput
        temp_verts_1 = []
        temp_verts_2 = {}
        for poly in output_data["polys"]:
        	vertices = poly["vertices"]
        	for vertex in vertices:
        		if not vertex in temp_verts_1:
        			temp_verts_1.append(vertex)
        for i, point in enumerate(input_data["points"]):
        	if i in temp_verts_1:
        		temp_verts_2[i] = len(output_data["points"])
        		output_data["points"].append(point)

        #Fix the vertices in the output
        for poly in output_data["polys"]:
        	vertices = poly["vertices"]
        	for i, vertex in enumerate(vertices):
        		vertices[i] = temp_verts_2[vertex]

        #Create the output file
        json_output_file = self.interpreter.filePool.create_file(suffix=".json")
        json_output_file_path = os.path.abspath(json_output_file.name)
        with open(json_output_file_path, 'w') as output:    
            output.write(json.dumps(output_data))

        #Set output
        self.setResult("json_output_file", json_output_file)

    _input_ports = [
    	("json_input_file",FILE,{"optional":False,"sort_key":1}),
    	("filter_data",STRING_STRING,{"optional":False,"sort_key":2})
    ]

    _output_ports = [
    	("json_output_file",FILE,{"optional":False,"sort_key":1})
    ]

''' ---------------------------------------------------------------------------
TransAddScalars
--------------------------------------------------------------------------- '''
class TransAddScalars(Module):
    def compute(self):

        # Check inputs
        if not self.hasInputFromPort("json_input_file"):
            raise ModuleError(self, "Needs json_input")
        if not self.hasInputFromPort("scalars_list"):
            raise ModuleError(self, "Needs scalars_list")
        if not self.hasInputFromPort("scalars_range"):
            raise ModuleError(self, "Needs scalars_range")
        json_input_file = self.getInputFromPort("json_input_file")
        scalars_list = self.getInputFromPort("scalars_list")
        scalars_range = self.getInputFromPort("scalars_range")

        #Normalise scalars from range
        min_val = scalars_range[0]
        max_val = scalars_range[1]
        dif_val = max_val - min_val
        scalars_list = [(i - min_val)/dif_val  for i in scalars_list]

        #Get the paths of the files
        json_input_file_path = os.path.abspath(json_input_file.name)

        #Get the json data
        with open(json_input_file_path) as input:    
            data = json.load(input)

        #Check that we have the right number of scalars
        if len(data["points"]) != len(scalars_list):
        	raise ModuleError(self, "Scalars list does not match the number of points. " + str(len(scalars_list)) + " : " + str(len(data["points"])))

        #Add the list to the data
        data["scalars"]=scalars_list

        #Create the output file
        json_output_file = self.interpreter.filePool.create_file(suffix=".json")
        json_output_file_path = os.path.abspath(json_output_file.name)
        with open(json_output_file_path, 'w') as output:    
            output.write(json.dumps(data))

        #Set output
        self.setResult("json_output_file", json_output_file)

    _input_ports = [
    	("json_input_file",FILE,{"optional":False,"sort_key":1}),
    	("scalars_list",LIST,{"optional":False,"sort_key":2}),
    	("scalars_range",FLOAT_FLOAT,{"optional":False,"sort_key":3})
    ]

    _output_ports = [
    	("json_output_file",FILE,{"optional":False,"sort_key":1})
    ]